var stats = new Stats(),
    sds = stats.domElement.style;
sds.position = 'absolute';
sds.top = '0px';
sds.right = '0px';
document.body.appendChild(stats.domElement);

if(!Math.sign) {
    Math.sign = function(x) {
        return ((x > 0) - (x < 0)) || +0;
    }
}

//=========

var c = document.getElementById('c'),
    ctx = c.getContext('2d'),
    width, height, particles = [];

var step = 7,
    counter = 0;

function init() {
    height = window.innerHeight * window.devicePixelRatio;
    width = window.innerWidth * window.devicePixelRatio;
    c.width = width;
    c.height = height;

    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, c.width, c.height);
    ctx.fillStyle = '#000';

    var fontSize = Math.min(height, width) / 2.5;

    step = Math.floor(fontSize / 25);

    ctx.font = `${fontSize}px Arial`;
    ctx.textAlign = 'center';

    ctx.fillText('Hello', width / 2, height / 2 + fontSize / 4);

    var data = ctx.getImageData(0, 0, width, height).data;
    var data32  = new Uint32Array(data.buffer);

    for(var x = 0; x < width; x += step) {
        for(var y = 0; y < height; y += step) {
            var pix = data32[y * width + x];
            if(pix != 0xffffffff) {
                particles.push({x: x, y: y});
            }
        }
    }
}

init();

window.addEventListener('resize', init, false);

function draw() {
    ctx.fillStyle = '#1c1c1c';
    ctx.fillRect(0, 0, c.width, c.height);

    for(var i = 0; i < particles.length; i += 1) {
        var dy = step * Math.cos(i * 3 + counter),
            radius = step * .5 * (dy < -1 ? 1 / Math.abs(dy) : 1);

        ctx.beginPath();
        ctx.arc(particles[i].x, particles[i].y + dy, radius, 0, Math.PI * 2, false);
        ctx.closePath();
        var color = (60 * Math.sign(dy) + 250) % 360;
        ctx.fillStyle = `hsl(${color}, 100%, 50%)`;
        ctx.fill();
    }
    counter += .1;
    requestAnimationFrame(draw);
    stats.update();
}

draw();